const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*`;
const qnameCapture = `((?:${ncname}\\:)?${ncname})`;
const startTagOpen = new RegExp(`^<${qnameCapture}`); // 标签开头的正则 捕获的内容是标签名
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`); // 匹配标签结尾的 </div>
const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/; // 匹配属性的
const startTagClose = /^\s*(\/?)>/; // 匹配标签结束的 >




export function parseHtml(html) {
    const ELEMENT_TYPE = 1
    const TEXT_TYPE = 3
    const stack = [];
    let currentTag;
    let root;


    function createASTElement(tagName, attrs) {
        return {
            tags: tagName,
            children: [],
            parent: null,
            type: ELEMENT_TYPE,
            attrs
        }
    }

    function start(tagname, attr) {
        let node = createASTElement(tagname, attr)
        if (!root) {
            root = node
        }

        if (currentTag) {
            node.parent = currentTag
            currentTag.children.push(node)
        }

        stack.push(node)
        currentTag = node
    }

    function char(text) {
        text = text.replace(/\s/g, '')
        text && currentTag.children.push({
            text,
            type: TEXT_TYPE,
            parent: currentTag
        })

    }

    function end() {
        stack.pop()
        currentTag = stack[stack.length - 1]
    }

    function advance(v) {
        html = html.substring(v)
    }

    function parseStartTag() {
        let tagStart = html.match(startTagOpen)

        if (tagStart) {
            const match = {
                tagName: tagStart[1],
                attrs: []
            }
            advance(tagStart[0].length)
            let attrArr, endMatch // || (end = !html.match(endTag))
            while (!(endMatch = html.match(startTagClose)) && (attrArr = html.match(attribute))) {
                advance(attrArr[0].length)
                match.attrs.push({
                    name: attrArr[1],
                    value: attrArr[3] || attrArr[4] || attrArr[5]
                })

            }
            if (endMatch) {
                advance(endMatch[0].length)
                return match
            }
        }
    }

    while (html) {
        let textEnd = html.indexOf('<')
        if (textEnd == 0) { // 如果有开始标签<
            let startTagMatch = parseStartTag()
            if (startTagMatch) { // 匹配道内容 
                start(startTagMatch.tagName, startTagMatch.attrs)  // <div>
                continue
            }
            let endTagMatch = html.match(endTag)
            if (endTagMatch) {
                advance(endTagMatch[0].length) // 删除此标签 </div>
                end(endTagMatch[1])
                continue
            }
        }
        let text;
        if (textEnd > 0) {  // 当前为结束标签
            text = html.substring(0, textEnd) // 获取此结束标签前的所有文本
        }
        if (text) {
            advance(text.length) // 删除此标签
            char(text)

        }
        // break

    }
    return root
}

